package com.example.bean;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


public class Solucion implements Comparable<Solucion>
{
		
	private ArrayList<Integer> nodos;
		
	private int permutacion[];
	private ArrayList<Integer> permuOcupada;
		
	private Long valorFuncionObjetivo;
	
	
	public Solucion() {
		nodos = new ArrayList<Integer>();
		permutacion = null;
		permuOcupada = null;
		valorFuncionObjetivo = 0L;
	}
		
	public Solucion (List<Integer> nodos, List<List<Long>> matrizDistancias) {

		permuOcupada = new ArrayList<Integer>();
		
		for (int i = 0; i < nodos.size(); i++) {
		    permuOcupada.add(0);
		}
		
		int[] permutacion = permutacionAleatoria(nodos.size());
		this.permutacion = permutacion;  
		
		valorFuncionObjetivo = calcularDistancia(permutacion, matrizDistancias);

	}
	
	
	public Solucion (int[] permutacion, ArrayList<Integer> rec, List<List<Long>> matrizDistancias) {
		nodos = new ArrayList<Integer>();
		permuOcupada = new ArrayList<Integer>();
		
		for (int i = 0; i < rec.size(); i++) {
		    permuOcupada.add(0);
		}
		
		this.permutacion = permutacion;
		
		valorFuncionObjetivo = calcularDistancia(permutacion, matrizDistancias);
		
	}
	
	public Long calcularDistancia(int[] permutacion, List<List<Long>> matrizDistancias){
		Long distancia = 0L;
		
		int origen = 0;
		int destino = 0;
		
		for(int i=0;i<permutacion.length-1;i++){
			
			origen = permutacion[i];
			destino = permutacion[i+1];
			
			distancia = distancia + matrizDistancias.get(origen).get(destino);
		}
				
		return distancia;
	}
	
	
	private int[] permutacionAleatoria (int size) {
		permutacion = new int[size+1];
		
		ArrayList<Integer> listaAPermutar = new ArrayList<Integer>();		
		
		for (int i = 0; i < size; i++){
			listaAPermutar.add(i);
		}
		
		do{
			Collections.shuffle(listaAPermutar);
		} while(listaAPermutar.get(0)!=0);
		
		for (int i = 0; i < size; i++){
			permutacion[i] = listaAPermutar.get(i);
		}
		permutacion[permutacion.length-1] = 0;
		return permutacion;
	}
				
		
	/**
	 * Metodo que devuelve la permutacion de la solucion.
	 * 
	 * @return Permutacion
	 */
	public int[] getPermutacion() {
		return permutacion.clone();
	}

	
	/**
	 * Metodo que devuelve el valor de la funcion objetivo de la solucion.
	 * 
	 * @return Objetivo
	 */
	public Long getValorFuncionObjetivo() {
		return valorFuncionObjetivo;
	}

	
		
	
	/**
	 * Metodo que compara dos soluciones y determina cual es el mayor en funcion
	 * de su valor de la F. Objetivo.
	 * 
	 * @param s Solucion a comparar.
	 * @return 1, 0 o -1 en funcion de si la solucion es
	 * mayor, igual o menor la solucion comparada.
	 */
	public int compareTo(Solucion s)
	{
		return ((Long)valorFuncionObjetivo).compareTo(s.getValorFuncionObjetivo());
	}

}
